﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FlatRedBall;
using FlatRedBall.Graphics;
using FlatRedBall.Graphics.Animation;
using FlatRedBall.Input;
using FlatRedBall.Math.Geometry;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;

using BulletHellBoxes.Utilities;

namespace BulletHellBoxes.GameObjects
{
    public class Bullet : GameObject
    {
        #region Constants
        private const float BASE_VELO = 10.0f;
        private const float SCALE = 0.25f;

        private const float BULLET_X_BOUND = 35.0f;
        private const float BULLET_Y_BOUND = 25.0f;
        #endregion

        #region Fields
        private Circle _collision;
        private double _timeStamp;
        #endregion

        #region Properties
        public Circle Collision
        {
            get { return _collision; }
        }

        public bool Active
        {
            get { return _sprite.Visible; }
        }
        #endregion

        #region Constructor
        public Bullet()
        {
            PATH = @"Content/GameObjects/Bullet/";
            NUM_FRAMES = 6;
            FRAME_TIME = 0.02f;

            Initialize();
        }
        #endregion

        #region Initialization Methods
        protected override void Initialize()
        {
            base.Initialize();

            _sprite.ScaleX *= SCALE;
            _sprite.ScaleY *= SCALE;
            _sprite.Visible = false;

            _collision = ShapeManager.AddCircle();
            _collision.Radius = _sprite.ScaleX;
            _collision.AttachTo(this, false);
            _collision.Visible = false;
        }

        #endregion

        #region Staple Methods
        public override void Activity()
        {
            // Reset the Bullet if it goes off the screen.
            if (ExceedsBounds())
            {
                Reset();
            }
            else if (TimeManager.CurrentTime - _timeStamp > 5.0 && _sprite.Visible)
            {
                Reset();
            }
        }

        public void Shoot(Vector2 dir)
        {
            // Must be visible and stick must not be static in the middle
            if (!_sprite.Visible && !dir.Equals(Vector2.Zero))
            {

                // Set the base velocity
                RelativeVelocity.X = dir.X * BASE_VELO;
                RelativeVelocity.Y = dir.Y * BASE_VELO;

                _sprite.Visible = true;
                _timeStamp = TimeManager.CurrentTime;
            }
        }

        public override void Destroy()
        {
            base.Destroy();
        
            ShapeManager.Remove(_collision);
        }
        #endregion

        #region Private Methods
        private bool ExceedsBounds()
        {
            // Check if bullet exceeds the bounds of the screen.
            return (this.RelativeX > BULLET_X_BOUND || this.RelativeX < -BULLET_X_BOUND
                || this.RelativeY > BULLET_Y_BOUND || this.RelativeY < -BULLET_Y_BOUND);
        }

        private void Reset()
        {
            _sprite.Visible = false;
            this.RelativePosition = Vector3.Zero;
            this.RelativeVelocity = Vector3.Zero;
        }
        #endregion
    }
}
